#include "ArkTsObjectManager.h"
#include "common/common.h"
#include "manager/plugin_manager.h"
#include <hilog/log.h>
using namespace napiT;

static napi_value NAPI_Global_addTsObject(napi_env env, napi_callback_info info) {
    size_t argc = 2;
    napi_value args[2] = {nullptr};

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    Jsobject jsobject;
    napi_status status = napi_create_reference(env, args[0], 1, &jsobject.ref);
    if (status != napi_ok) {
        AKI_LOG(ERROR) << "fjx Failed to create reference";
        return nullptr;
    }

    jsobject.name = napiT::napiValueToString(env, args[1]);

    {
        std::lock_guard<std::mutex> lock(napiT::jsobjectMapMutex);
        napiT::jsobjectMap[jsobject.name] = jsobject;
    }

    AKI_LOG(INFO) << "fjx Stored prototype: " << jsobject.name << "fjx in thread: " << std::this_thread::get_id();
    return nullptr;
}

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Init", "Initializing native module");

    napiT::g_jsEnv = env;
    napi_get_uv_event_loop(env, &napiT::g_jsLoop);

    if (napiT::g_jsEnv == nullptr || napiT::g_jsLoop == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Init", "Failed to initialize JS environment");
        return nullptr;
    }

    napi_property_descriptor desc[] = {
        {"getContext", nullptr, PluginManager::GetContext, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"addTsObject", nullptr, NAPI_Global_addTsObject, nullptr, nullptr, nullptr, napi_default, nullptr}};

    if (napi_ok != napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Init", "Failed to define properties");
        return nullptr;
    }

    PluginManager::GetInstance()->Export(env, exports);

    AKI_LOG(INFO) << "Native module initialized successfully";
    return exports;
}
EXTERN_C_END

static napi_module nativerenderModule = {.nm_version = 1,
                                         .nm_flags = 0,
                                         .nm_filename = nullptr,
                                         .nm_register_func = Init,
                                         .nm_modname = "nativerender",
                                         .nm_priv = nullptr,
                                         .reserved = {0}};

extern "C" __attribute__((constructor)) void RegisterModule(void) {
    napi_module_register(&nativerenderModule);
    AKI_LOG(INFO) << "Native module registered";
}